﻿using ReflectionStudio.Core.Events;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using WPFExcelReport.Controls;
using WPFExcelReport.Helpers;
using System;
namespace WPFExcelReport
{
    public partial class UIAM
    {

        private DataTable _TBRILI;
        public DataTable TBRILI
        {
            get
            {
                if (_TBRILI == null)
                {
                    dwData = TMV.VMK.TBMain.NewRow();
                    dwData["ABFBNRKRS"] = MKEY.Substring(0, 2);
                    dwData["ABFBLFDNR"] = MKEY.Substring(2, 4);
                    dwData["ABFBPOS"] = MKEY.Substring(6, 2);
                    dwData["MKFPLDATV"] = TMV.date;
                    dwData["JOBTYPE"] = "X";
                    SResult = TMV.VMK.QTMKRF14(dwData);
                    foreach (DataRow row in SResult.Tables[0].Rows)
                    {
                        row["JP49"] = 0;
                    }
                    _TBRILI = SResult.Tables[0].Copy();
                    AvailibleRili = _TBRILI.Rows.Count;
                }
                return _TBRILI;
            }
            set
            {
                _TBRILI = value;
            }
        }
        private DataTable _TBWD;
        public DataTable TBWD
        {
            get
            {
                if (_TBWD == null)
                {
                    dwData = TMV.VMK.TBMain.NewRow();
                    dwData["ABFBNRKRS"] = MKEY.Substring(0, 2);
                    dwData["ABFBLFDNR"] = MKEY.Substring(2, 4);
                    dwData["ABFBPOS"] = MKEY.Substring(6, 2);
                    dwData["MKFPLDATV"] = TMV.date;
                    dwData["JOBTYPE"] = "W";
                    long now = System.DateTime.Now.ToFileTime();
                    SResult = TMV.VMK.QTMKRF14(dwData);

                    foreach (DataRow row in SResult.Tables[0].Rows)
                    {
                        if (long.Parse(row["SFILETME"].ToString()) < now)
                        {
                            TMV.WD = int.Parse(row["JP02"].ToString());
                            continue;
                        }
                        break;
                    }
                    dwData["SFILETME"] = System.DateTime.Now.AddMinutes(-1440).ToFileTime();
                    TMV.VMK.DMKRF05(dwData);
                    _TBWD = SResult.Tables[0].Copy();

                }
                return _TBWD;
            }
            set
            {
                _TBWD = value;
            }
        }


        public DataTable SPSPIN;
        public string LastEndDate { get { return dwMachine["AMAENDDAT"].ToString(); } set { dwMachine["AMAENDDAT"] = value; } }
        public string LastEndTime { get { return dwMachine["AMNEUDAT"].ToString(); } set { dwMachine["AMNEUDAT"] = value; } }
        public string LastIndex { get { return dwMachine["AMAENDZL"].ToString(); } set { dwMachine["AMAENDZL"] = value; } }

        public double SpinSpeed(DataRow dwJob, ref bool IsFinished)
        {
            if (SPSPIN.Rows.Count == 0)
                return 0;
            double times = 0;
            double YN = Convert.ToDouble(dwJob["JP01"].ToString());
            string JOBTYPE = dwJob["JOBTYPE"].ToString();//类型
            double ABFISTARTDAT = Convert.ToDouble(dwJob["ABFISTARTDAT"].ToString());//实际开始日期
            int MKFSME = Convert.ToInt16(dwJob["MKFSME"].ToString());
            double MKFSMG = 0.01 * Convert.ToDouble(dwJob["MKFSMG" + MKFSME].ToString());
            double ABFIMG = 0.001 * Convert.ToDouble(dwJob["ABFIMG"].ToString());
            if (Math.Abs(MKFSMG - ABFIMG) < 200)
            {
                IsFinished = true;
            }

            var query = from DataRow row in SPSPIN.AsEnumerable()
                        where Convert.ToDouble(row["YN"].ToString()) >= YN
                        orderby Convert.ToDouble(row["YN"].ToString()) ascending
                        select row;
            foreach (DataRow row in query)
            {
                double daily = Convert.ToDouble(row["MDAILY"].ToString());
                times = Math.Round((ABFIMG / daily) + ((MKFSMG - ABFIMG) / daily)) * 24 * 60;
                break;
            }
            return Helper.RoundX(times, 1);
        }


        int AvailibleRili = 0;
        public virtual double CalculateProcessingTime(DataRow dwJob)
        {
            double processtime = 0;
            bool IsFinished = false;
            if (SPSPIN != null)
            {
                processtime = SpinSpeed(dwJob, ref IsFinished);
            }
            if (processtime > 0)
                return processtime;
            if (IsFinished)
                return 100.0;
            //processtime = SpinSpeed(dwJob, ref IsFinished);
            string ABFFIX = dwJob["ABFFIX"].ToString();
            string ABFMASCHZE = dwJob["ABFMASCHZE"].ToString();

            double MINH = 1;
            if (ABFMASCHZE == "ST") MINH = 60;

            //double ABFMASCHANZ = Convert.ToDouble(dwJob["ABFMASCHANZ"].ToString()) * 0.0001;
            double ABFMASCHZT = 0.01 * Convert.ToDouble(dwJob["ABFMASCHZT"].ToString());
            if (ABFFIX == "N")
            {
                double ABFIMG = 0.001 * Convert.ToDouble(dwJob["ABFIMG"].ToString());
                double ABFBASMGE = 0.001 * Convert.ToDouble(dwJob["ABFBASMGE"].ToString());
                int MKFSME = Convert.ToInt16(dwJob["MKFSME"].ToString());
                double MKFSMG = 0.01 * Convert.ToDouble(dwJob["MKFSMG" + MKFSME].ToString());

                if (ABFBASMGE == 0)
                    ABFBASMGE = 1;
                processtime = MINH * ABFMASCHZT * ABFIMG / ABFBASMGE + MINH * ABFMASCHZT * (MKFSMG - ABFIMG) / ABFBASMGE;
            }
            else
            {
                processtime = MINH * ABFMASCHZT;
            }
            processtime = Math.Round(processtime);
            if (processtime == 0)
                processtime = 600;

            return processtime;
        }

        public virtual DateTime GETAMREDY(DataRow dwJob)
        {
            DateTime UIAMReady;
            string LASEENDD = dwMachine["AMAENDDAT"].ToString();
            string LASTENDT = Helper.Right("0000" + dwMachine["AMNEUDAT"].ToString(), 4);
            //string Endnum = dwMachine["AMAENDZL"].ToString();
            int year = 2014, month = 1, day = 1, hh = 12, mm = 0, second = 0;
            Helper.SplitDate(ref year, ref month, ref day, LASEENDD);
            Helper.SplitTime(ref hh, ref mm, LASTENDT);
            UIAMReady = new DateTime(year, month, day, hh, mm, second);//最早可以开始时间

            TMV.JJRULES.RValidate(JJRules, dwMachine, dwMJob, dwJob);
            double JJTime = Convert.ToDouble(dwMachine["JJVALUE"].ToString());
            UIAMReady = UIAMReady.AddMinutes(JJTime);
            return UIAMReady;
        }
        public virtual DateTime GETAMREDYBYCOST(DataRow dwJob)
        {
            DateTime UIAMReady;
            string LASEENDD = dwMachine["AMAENDDAT"].ToString();
            string LASTENDT = Helper.Right("0000" + dwMachine["AMNEUDAT"].ToString(), 4);
            //string Endnum = dwMachine["AMAENDZL"].ToString();
            int year = 2014, month = 1, day = 1, hh = 12, mm = 0, second = 0;
            Helper.SplitDate(ref year, ref month, ref day, LASEENDD);
            Helper.SplitTime(ref hh, ref mm, LASTENDT);
            UIAMReady = new DateTime(year, month, day, hh, mm, second);//最早可以开始时间
            TMV.JJRULES.WD = TMV.WD;
            TMV.JJRULES.RCOSTValidate(JJRules, dwMachine, dwMJob, dwJob);
            double JJTime = Convert.ToDouble(dwMachine["JJVALUE"].ToString());
            UIAMReady = UIAMReady.AddMinutes(JJTime);
            return UIAMReady;
        }
        public virtual void GetLockDateTime(DataRow dwNJob, double ProcessTime, ref DateTime JobStart, ref DateTime JobEnd, ref double locktime, ref string RIID)
        {

            DateTime UIAMReady = GETAMREDY(dwNJob);
            //设备10分好了，任务20分钟后
            //设备10分好，任务5分好，以设备为准，否则以任务准
            if (UIAMReady > JobStart)
                JobStart = UIAMReady;
            JobEnd = JobStart.AddMinutes(Convert.ToDouble(ProcessTime));


            //如果连续多个事件该如何处理？ 
            if (AvailibleRili == 0)
                return;

            var query = from DataRow dwJob in TBRILI.AsEnumerable()
                        where dwJob["JOBTYPE"].ToString().Trim() == "X"
                        && dwJob["JP49"].ToString().Trim() == "0"
                        orderby Convert.ToDouble(dwJob["ABAID"].ToString()) ascending
                        select dwJob;
            foreach (DataRow dwJob in TBRILI.Rows)
            {
                long SFILETME = long.Parse(dwJob["SFILETME"].ToString());
                long EFILETME = long.Parse(dwJob["EFILETME"].ToString());

                string cstartdate = dwJob["MKFPLDATV"].ToString();
                string cstarttime = dwJob["MKFPLTIME"].ToString();
                string cenddate = dwJob["ENDATE"].ToString();
                string cendtime = dwJob["ENDTIME"].ToString();
                if (JobEnd.ToFileTime() < SFILETME)//事件之前结束
                    break;
                if (JobStart.ToFileTime() < SFILETME && JobEnd.ToFileTime() > SFILETME)//任务结束前遇到事件
                {
                    RIID = dwJob["ABAID"].ToString();
                }
            }
        }
        public virtual void LockDateTimeBYcost(DataRow dwNJob, double ProcessTime, ref DateTime JobStart, ref DateTime JobEnd, ref double locktime, ref string RIID)
        {
            DateTime UIAMReady = GETAMREDYBYCOST(dwNJob);
            //设备10分好了，任务20分钟后
            //设备10分好，任务5分好，以设备为准，否则以任务准
            if (UIAMReady > JobStart)
                JobStart = UIAMReady;
            JobEnd = JobStart.AddMinutes(Convert.ToDouble(ProcessTime));
        }

        public virtual void LockRili(string ABAID)
        {
            filter = "ABAID='" + ABAID + "'";
            rows = TBRILI.Select(filter);
            foreach (DataRow dwJob in rows)
            {
                dwJob["JP49"] = 2;
                AvailibleRili--;

                DateTime JobStart = new DateTime();
                DateTime JobEnd;
                Helper.GetDateTime(ref JobStart, LastEndDate, LastEndTime);
                JobEnd = JobStart.AddMinutes(double.Parse(dwJob["ABFAMASCHZT"].ToString()));
                dwJob["SFILETME"] = JobStart.ToFileTime();
                dwJob["EFILETME"] = JobEnd.ToFileTime();
                string jdstart = "", jtstart = "";
                Helper.GetStdDate(ref jdstart, ref jtstart, JobStart);
                dwJob["MKFPLDATV"] = jdstart;
                dwJob["MKFPLTIME"] = jtstart;
                Helper.GetStdDate(ref jdstart, ref jtstart, JobEnd);
                dwJob["ENDATE"] = jdstart;
                dwJob["ENDTIME"] = jtstart;
                LastEndDate = jdstart;    //AMAENDDAT
                LastEndTime = Helper.Right("0000" + jtstart.ToString(), 4);    //AMNEUDAT
                LastIndex = ((Convert.ToInt16(LastIndex)) + 1).ToString();
                break;
            }
        }

        public virtual void PushJob(DataRow dwJob)
        {
            try
            {


                double ProcessTime = CalculateProcessingTime(dwJob);
                string RILIID = "";
                double locktime = 0;
                string matreadydate = dwJob["MATREADYDATE"].ToString();//MATREADYDATE
                string matreadytime = dwJob["MATREADYTIME"].ToString();//MATREADYTIME
                if (matreadydate == "0")
                {
                    if (dwJob["JOBTYPE"].ToString() == "P")
                    {
                        matreadydate = dwJob["ABFISTARTDAT"].ToString();
                        matreadytime = dwJob["ABFISTARTZT"].ToString();

                    }
                    else
                    {
                        matreadydate = LastEndDate;
                        matreadytime = LastEndTime;
                    }
                }
                DateTime JobStart = new DateTime();
                DateTime JobEnd = new DateTime();
                Helper.GetDateTime(ref JobStart, matreadydate, matreadytime);
                //找到日历后，立刻把日历放在任务上
                GetLockDateTime(dwJob, ProcessTime, ref JobStart, ref JobEnd, ref locktime, ref RILIID);//
                dwJob["SFILETME"] = JobStart.ToFileTime();
                dwJob["EFILETME"] = JobEnd.ToFileTime();

                dwJob["ABFBNRKRS"] = dwMachine["AMNRKRS"];
                dwJob["ABFBLFDNR"] = dwMachine["AMLFDNR"];
                dwJob["ABFBPOS"] = dwMachine["AMPOS"];
                dwJob["MACHINEID"] = dwMachine["MACHINEID"].ToString();
                string jdstart = "", jtstart = "";
                Helper.GetStdDate(ref jdstart, ref jtstart, JobStart);
                dwJob["MKFPLDATV"] = jdstart;
                dwJob["MKFPLTIME"] = jtstart;
                dwJob["ABFAMASCHZT"] = ProcessTime;//应当把结束时间单独保存，加工时间另外保存
                dwJob["MKFLFDNR"] = LastIndex;
                dwJob["MKFSCHICHTV"] = 1;

                Helper.GetStdDate(ref jdstart, ref jtstart, JobEnd);
                LastEndDate = jdstart;    //AMAENDDAT
                LastEndTime = Helper.Right("0000" + jtstart.ToString(), 4);    //AMNEUDAT
                LastIndex = ((Convert.ToInt16(LastIndex)) + 1).ToString();
                dwJob["ENDATE"] = jdstart;
                dwJob["ENDTIME"] = jtstart;
                string ABFSOLLDAT = dwJob["ABFSOLLDAT"].ToString();
                if (ABFSOLLDAT == "0") ABFSOLLDAT = "19000101";
                DateTime JobPlanEnd = new DateTime(int.Parse(ABFSOLLDAT.Substring(0, 4)), int.Parse(ABFSOLLDAT.Substring(4, 2)), int.Parse(ABFSOLLDAT.Substring(6, 2)));
                dwJob["JP12"] = (JobEnd - JobStart).Days;
                dwMJob = dwJob.Table.Clone().Rows.Add();
                dwMJob.ItemArray = dwJob.ItemArray;
                LockRili(RILIID);
                filter = "SFILETME<'" + JobEnd.ToFileTime() + "'";
                rows = TBWD.Select(filter);
                foreach (DataRow row in rows)
                {
                    TMV.WD = Math.Abs(TMV.WD - 1);
                    TMV.VMK.CopyWD(row);
                }
                LogHelper.info(MachineID + ":" + dwMJob["ABAID"].ToString());
            }
            catch (Exception ex)
            {
                LogHelper.error(ex.Message);
            }
        }

        public virtual void PlanJob(DataRow dwJob)
        {
            double ProcessTime = CalculateProcessingTime(dwJob);
            string RILIID = "";
            double locktime = 0;
            DateTime JobStart = new DateTime();
            DateTime JobEnd = new DateTime();
            GetLockDateTime(dwJob, ProcessTime, ref JobStart, ref JobEnd, ref locktime, ref RILIID);
            dwJob["SFILETME"] = JobStart.ToFileTime();
            dwJob["EFILETME"] = JobEnd.ToFileTime();
            if (locktime > 0)
            {
                LockRili(RILIID);
            }
            dwJob["ABFBNRKRS"] = dwMachine["AMNRKRS"];
            dwJob["ABFBLFDNR"] = dwMachine["AMLFDNR"];
            dwJob["ABFBPOS"] = dwMachine["AMPOS"];
            dwJob["MACHINEID"] = dwMachine["MACHINEID"].ToString();
            string jdstart = "", jtstart = "";
            Helper.GetStdDate(ref jdstart, ref jtstart, JobStart);

            dwJob["ABFAMASCHZT"] = ProcessTime;//应当把结束时间单独保存，加工时间另外保存
            dwJob["MKFLFDNR"] = LastIndex;

            Helper.GetStdDate(ref jdstart, ref jtstart, JobEnd);
            LastEndDate = jdstart;
            LastEndTime = jtstart;
            LastIndex = ((Convert.ToInt16(LastIndex)) + 1).ToString();

        }

    }

}
